/**********************************************************
    COPYRIGHT
        KND, Inc. (c) 2011
    CLASS NAME
        platform_cpld.c
    DEPENDENCY

    HISTORY
		01/05/2012, created by Guangxing Liu
**********************************************************/
#include "platform_cpld.h"
#include "platform_config.h"
#include "platform_uart.h"
#include "lpc177x_8x_timer.h"
#include "lpc177x_8x_emc.h"

extern void Cpld_init(void);
extern void Cpld_write(uint32_t Adr, uint16_t data);
extern uint16_t Cpld_read(uint32_t Adr);


/************************************************************************
	FUNCTION NAME : platform_cpld_init
	INPUTS: 
		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		Platform cpld init
************************************************************************/
void platform_cpld_init(void)
{
	
}

/************************************************************************
	FUNCTION NAME : platform_cpld_device_open
	INPUTS: 
 		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		cpld Device Open
************************************************************************/
DeviceHandle platform_cpld_device_open(void)
{
	platform_cpld_app_call* handle = (platform_cpld_app_call*)malloc(sizeof(platform_cpld_app_call));
	if(handle)
	{
		handle->iOpt = Platform_Cpld_App_Call_None;
	}
	return (DeviceHandle)handle;
 }	

/************************************************************************
	FUNCTION NAME : platform_cpld_device_close
	INPUTS: 
		DeviceHandle handle
	OUTPUTS:	
		none
	DESCRIPTION:	
		cpld Device Close
************************************************************************/
int platform_cpld_device_close(DeviceHandle handle)
{
	platform_cpld_app_call* me = (platform_cpld_app_call*)handle;
	if(me)
	{
		free(me);
	}
	return 0;
	
}/************************************************************************
	FUNCTION NAME : platform_cpld_device_ioctl
	INPUTS: 
		DeviceHandle handle, const char *params
	OUTPUTS:	
		none
	DESCRIPTION:	
		cpld Device Control
************************************************************************/
int platform_cpld_device_ioctl(DeviceHandle handle, const char *params)
{
	platform_cpld_app_call* me = (platform_cpld_app_call*)handle;
	
	switch(*params)
	{
		case '0':
			me->iOpt = Platform_Cpld_App_Call_Cpld_Init;
			return 0;
		case '1':
			me->iOpt = Platform_Cpld_App_Call_Cpld_WriteWord;
			return 0;
		case '2':
			me->iOpt = Platform_Cpld_App_Call_Cpld_ReadWord;
			return 0;
			
		default:
			platform_printf("ERROR--platform_cpld_device_ioctl unkown params: %s\r\n",params);
			break;
	}

	return -1;
}

/************************************************************************
	FUNCTION NAME :platform_cpld_device_read
	INPUTS: 
		DeviceHandle handle, char *buf, int len
	OUTPUTS:	
		none
	DESCRIPTION:	
		cpld Device Read
************************************************************************/
int platform_cpld_device_read(DeviceHandle handle, void *buf, int len)
{
	platform_cpld_app_call* me = (platform_cpld_app_call*)handle;
	
	if(!me || !buf)
		return -1;
	switch(me->iOpt)
	{
		case 0:			
	         	return 0;
		case Platform_Cpld_App_Call_Cpld_ReadWord:
			{
				platform_cpld_value *value =(platform_cpld_value*)buf;

				value->Data=Cpld_read(value->Adr);
			}
			return 0;
		default:
			platform_printf("ERROR--platform_cpld_device_read unkown params: %s\r\n",me->iOpt);
			break;
	}
	
	return -1;

}

/************************************************************************
	FUNCTION NAME : platform_cpld_device_write
	INPUTS: 
		DeviceHandle handle,  const char *buf, int len
	OUTPUTS:	
		none
	DESCRIPTION:	
		cpld Device Write
************************************************************************/
int platform_cpld_device_write(DeviceHandle handle,  void *buf, int len)
{
	platform_cpld_app_call* me = (platform_cpld_app_call*)handle;
	if(!me || !buf)
		return -1;
	switch(me->iOpt)
	{
		case Platform_Cpld_App_Call_Cpld_Init:
			{
				Cpld_init();							
			}
			return 0;
		case Platform_Cpld_App_Call_Cpld_WriteWord:
			{
				platform_cpld_value *value =(platform_cpld_value*)buf;

				Cpld_write(value->Adr,value->Data);
				
			}
			return 0;
		default:
			platform_printf("ERROR--platform_cpld_device_write unkown params: %s\r\n",me->iOpt);
			break;
	}
	return -1;

}
/************************************************************************
	FUNCTION NAME : platform_init_cpld_device
	INPUTS: 
		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		cpld Device Init
************************************************************************/
void platform_init_cpld_device(void)
{
	DeviceInterface cpld= {
                               platform_cpld_device_open,
                               platform_cpld_device_close,
                               platform_cpld_device_ioctl,
                               platform_cpld_device_read,
                               platform_cpld_device_write
                              };


	hyacinth_install_device(CPLD_DEVICE,&cpld);
}

/************************************************************************
	FUNCTION NAME : platform_finit_cpld_device
	INPUTS: 
		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		cpld Device Finit
************************************************************************/
void platform_finit_cpld_device(void)
{
	hyacinth_uninstall_device(CPLD_DEVICE);
}

/************************************************************************
	FUNCTION NAME :Cpld_init
	INPUTS: 
		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		 cpld init
************************************************************************/
void Cpld_init()
{
  	int i = 0;
	TIM_TIMERCFG_Type TIM_ConfigStruct;
	
	EMC_Init();
/*	LPC_GPIO1 -> DIR  |= (0x1<<18);
	LPC_GPIO1 -> CLR  |= (0x1<<18);
	    // init timer
	TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
	TIM_ConfigStruct.PrescaleValue	= 1;

		// Set configuration for Tim_config and Tim_MatchConfig
	TIM_Init(LPC_TIM0, TIM_TIMER_MODE,&TIM_ConfigStruct);
	TIM_Waitms(100);
*/	
	LPC_EMC->StaticConfig1 = (LPC_EMC->StaticConfig1 & 0xFFFFFFFC) | 0x01;
	LPC_EMC->StaticConfig1 = (LPC_EMC->StaticConfig1 & 0xFFFFFF7F) | ((uint32_t )(1 << 7)) ;
	LPC_EMC->StaticConfig1 = (LPC_EMC->StaticConfig1 & 0xFFFFFEFF) | ((uint32_t )(1 << 8)) ;
	LPC_EMC->StaticWaitWen1 = 0x02;
	LPC_EMC->StaticWaitOen1 = 0x02;
	LPC_EMC->StaticWaitRd1 = 0x1f;
	LPC_EMC->StaticWaitPage1 = 0x1f;
	LPC_EMC->StaticWaitWr1 = 0x1f;
	LPC_EMC->StaticWaitTurn1 = 0x1f;
	LPC_EMC->StaticExtendedWait = 0x5;
 
		//delay time
 	//TIM_Waitms(10);
	for(i = 0; i < 100000; i++);
}
/************************************************************************
	FUNCTION NAME :Cpld_write
	INPUTS: 
		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		 cpld write
************************************************************************/
void Cpld_write(uint32_t Adr, uint16_t data)
{
	volatile uint16_t *ip;

	LPC_GPIO0 -> DIR  |= (0x1<<6); 
	LPC_GPIO0 -> DIR  |= (0x1<<7);
	LPC_GPIO0 -> DIR  |= (0x1<<8);

	LPC_GPIO0 -> SET  |= (0x1<<6);

	ip  = (volatile uint16_t *)(CPLD_BASE_ADDRESS+(Adr << 1));
	*ip = data;
}


/************************************************************************
	FUNCTION NAME :Cpld_read
	INPUTS: 
		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		 
************************************************************************/
uint16_t Cpld_read(uint32_t Adr)
{
	uint16_t data;
	volatile uint16_t *ip;

	ip  =(volatile uint16_t *)(CPLD_BASE_ADDRESS+(Adr << 1));
	data = *ip;

	return data;

}

















